﻿using System;
using System.Reflection;
using System.Diagnostics;

namespace Heaven.Diagnostics
{
    /// <summary>
    /// Тест, извлеченный из сборки
    /// </summary>
    public class Test
    {
        #region Аттрибуты

        // Название группы теста
        private string groupName;
        // Название теста
        private string methodName;
        // Объект, содержащий 
        // реальные тестовые методы
        private object owner;
        // Реальный тестовый метод 
        // соответствующий данному тесту
        private MethodInfo method;

        // Результаты проведения тестов
        Collector result = new Collector();

        #endregion

        #region Конструкторы

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="groupName">Название группы тестов</param>
        /// <param name="methodName">Название теста</param>
        /// <param name="owner">Класс-владелец теста (требуется для запуска теста)</param>
        /// <param name="method">Метаданные метода, представляющего из себя тест</param>
        public Test(string groupName, string methodName, object owner, MethodInfo method)
        {
            this.groupName = groupName;
            this.methodName = methodName;
            this.owner = owner;
            this.method = method;
        }

        #endregion

        #region Методы и свойства

        /// <summary>
        /// Название группы (только чтение)
        /// </summary>
        /// <value>Строка, название группы</value>
        public string Group
        {
            get { return groupName; }
        }

        /// <summary>
        /// Название теста (только чтение)
        /// </summary>
        /// <value>Строка, название теста</value>
        public string Name
        {
            get { return methodName; }
        }

        /// <summary>
        /// Результат проведенных тестов
        /// </summary>
        public Collector Result
        {
            get { return result; }
        }

        /// <summary>
        /// Запуск теста
        /// </summary>
        public void Diagnose()
        {
            Collector accumulator = new Collector();
            long starttime = Stopwatch.GetTimestamp();

            try
            {
                int c = method.GetParameters().Length;
                if (c == 1)
                {
                    if(accumulator.GetType() == method.GetParameters()[0].ParameterType)
                    {
                        accumulator.Start();
                        method.Invoke(owner, new object[] { accumulator });
                    }
                    else throw new Exception("В тестовый метод нужно передавать параметр типа Collector");
                }
                else throw new Exception("В тестовый метод нужно передавать только один параметр");
            }
            catch (Exception exc)
            {
                if (exc.InnerException != null)
                {
                    accumulator.Exception = exc.InnerException;
                }
                else accumulator.Exception = exc;
            }

            // Запоминаем результаты
            result = accumulator;
        }

        #endregion
    }
}
